package customer.design.dispatcher.dispatchermode.util;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;

import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class test {
    public static void main(String[] args) throws Exception {
        Map<String, Object> prodMap = new HashMap<>();
        prodMap.put("name", "haier");
        prodMap.put("no", "1234568889");
        List<Object> priceList = new ArrayList<>();
        Map<String, Object> priceMap = new HashMap<>();
        priceMap.put("price", "1000");
        priceMap.put("type", "深圳产地");
        priceMap.put("date", "20230613");
        priceList.add(priceMap);
        prodMap.put("productInfoList", priceList);
        ProductA productA1 = JSON.parseObject(JSONObject.toJSONString(prodMap), ProductA.class);
        for (ProductInfo productInfo : productA1.getProductInfoList()) {
            System.out.println(productInfo);
        }
        Object o = convert(prodMap, ProductA.class);
        System.out.println(o);
    }
    public static <T> T convert(Map<String, Object> map, Class<T> clazz) throws Exception {
        T obj = clazz.getDeclaredConstructor().newInstance();
        for (String key : map.keySet()) {
            Object value = map.get(key);
            if (value != null) {
                Field field = clazz.getDeclaredField(key);
                field.setAccessible(true);
                if (field.getType().equals(value.getClass())) {
                    field.set(obj, value);
                }else if(value instanceof List){
                     List value1 = (List)value;
                    for (Object o : value1) {
                        if (value instanceof Map) {
                            Class<?> fieldClass = field.getType();
                            if (fieldClass.equals(List.class)) {
                                ParameterizedType genericType = (ParameterizedType) field.getGenericType();
                                Class<?> paramClass = (Class<?>) genericType.getActualTypeArguments()[0];
                                List<Object> subList = (List<Object>) value;
                                List<Object> objList = new ArrayList<>();
                                for (Object subObj : subList) {
                                    objList.add(convert((Map<String, Object>) subObj, paramClass));
                                }
                                field.set(obj, objList);
                            } else {
                                Object subObj = convert((Map<String, Object>) value, fieldClass);
                                field.set(obj, subObj);
                            }
                        }
                    }
                }
            }
        }
        return obj;
    }

    public static <T> T map2Bean(final Class<T> clazz, final Map<String, ? extends Object> map,List<Object> productInfoList, List<Object> typeList) {
        final String leftType = "java.util.List<";
        final String rightType = ">";
        if (map == null) {
            return null;
        }
        T res = null;
        try {
            res = clazz.getDeclaredConstructor().newInstance();
            //获取到所有属性，不包括继承的属性
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                String name = field.getType().getName();
                //设置对象的访问权限
                field.setAccessible(true);
                if ("java.util.List".equals(name)) {
                    String typeName = field.getGenericType().getTypeName();
                    if (typeName.contains(leftType) && typeName.contains(rightType)) {
                        typeName = typeName.replace(leftType, "").replace(rightType, "");
                        Class<?> aClass = Class.forName(typeName);
                        String subName = field.getName();
                        if (map.containsKey(subName)) {
                            Map<String, Object> subMap = (Map<String, Object>) map.get(subName);
                            for (int i = 0; i < subMap.entrySet().size(); i++) {
                                typeList.add(subName);
                                map2Bean(aClass, subMap,productInfoList,typeList);
                            }
                        }
                    }
                } else {
                    getValue(map, res, field);
                }
                if(typeList.size()>0){
                    for (Method method : res.getClass().getMethods()) {
                        Object defaultValue = method.getDefaultValue();
                    }
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(res);
        return res;
    }
    private static <T> T getValue(Map<String, ?> map, T res, Field field) throws IllegalAccessException {
        //获取字段的修饰符
        //根据属性名称去map获取value
        int mod = field.getModifiers();
        if (map.containsKey(field.getName())) {
            String typeName = field.getType().getTypeName();
            if ("int".equals(typeName)) {
                field.set(res, Integer.parseInt((String) map.get(field.getName())));
            } else {
                //给对象赋值
                field.set(res, map.get(field.getName()));
            }
        }
        return res;
    }

    //-------------------   reflect     -------------------
    //map转java对象
    public static Object reflectMapToObject(Map<String, Object> map, Class<?> beanClass) throws Exception {
        if (map == null) {
            return null;
        }
        Object object = beanClass.newInstance();
        Field[] fields = beanClass.getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();
            if (Modifier.isFinal(mod) || Modifier.isStatic(mod)) {
                continue;
            }
            field.setAccessible(true);
            field.set(object, map.get(field.getName()));
        }
        return object;
    }

    //java对象转map
    public static Map<String, Object> reflectObjectToMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            map.put(field.getName(), field.get(obj));
        }
        return map;
    }

}
